package com.example.tao.smartcar.wifi.socket;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import com.example.tao.smartcar.tool.DateTools;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by Tao on 2016/9/17.
 */
public class SocketClient {
    private Handler mHandler;
    private Handler mSendHandler;
    private String mIp;
    private int mPort;
    private ExecutorService sendPool;
    private ExecutorService heartBeatPool;
    private ExecutorService receivePool;
    private boolean heartBeatRunning;
    private String mReceiveData;
    public boolean dataValid = false;

    public static int MSG_SEND = 0x11;
    public static int MSG_REV = 0x12;
    public static String DATA = "data";

    public SocketClient(){}

    public SocketClient(String ip, int port) {
        this.mIp = ip;
        this.mPort = port;
    }

    public void setHandler(Handler handler) {
        this.mHandler = handler;
    }

    public void setIp(String ip) {
        this.mIp = ip;
    }

    public void setPort(int port) {
        this.mPort = port;
    }

    public Handler getSendHandler () {
        if (mSendHandler != null)
            return mSendHandler;
        else
            return null;
    }

    public void send() {
        if (sendPool == null)
            sendPool = Executors.newFixedThreadPool(1);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                Socket socket = null;
                OutputStream out = null;
                try {
                    socket = new Socket(mIp, mPort);
                    out = socket.getOutputStream();
                    Looper.prepare();
                    final OutputStream finalOut = out;
                    mSendHandler = new Handler() {
                        @Override
                        public void handleMessage(Message msg) {
                            super.handleMessage(msg);
                            if (msg.what == MSG_SEND) {
                                Bundle bundle = msg.getData();
                                String data = bundle.getString(DATA);
                                try {
                                    finalOut.write(data.getBytes());
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    };
                    Looper.loop();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        };
        sendPool.submit(runnable);
    }

    public void startHeartBeat() {
        if (heartBeatPool == null)
            heartBeatPool = Executors.newFixedThreadPool(1);
        heartBeatRunning = true;
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                Socket socket = null;
                OutputStream out = null;
                try {
                    socket = new Socket(mIp, mPort);
                    out = socket.getOutputStream();
                    while (!Thread.currentThread().isInterrupted()) {
                        out.write(("HeartBeat: " + DateTools.getDate() + "\n").getBytes());
                        out.flush();
                        Thread.sleep(2000);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    //Thread.currentThread().interrupt();
                } finally {
                    try {
                        if (out != null)
                            out.close();
                        if (socket != null)
                            socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        heartBeatPool.submit(runnable);
    }

    public void stopHeartBeat() {
        if (heartBeatPool != null) {
            heartBeatPool.shutdownNow();
            heartBeatPool = null;
        }
    }

    public void receive() {
        if (receivePool == null)
            receivePool = Executors.newFixedThreadPool(1);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                Socket socket = null;
                InputStream in = null;
                BufferedReader br = null;
                try{
                    socket = new Socket(mIp, mPort);
                    in = socket.getInputStream();
                    br = new BufferedReader(new InputStreamReader(in));
                    while ((mReceiveData = br.readLine()) != null) {
                        Message msg = mHandler.obtainMessage();
                        msg.what = MSG_REV;
                        Bundle data = new Bundle();
                        data.putString(DATA, mReceiveData);
                        msg.setData(data);
                        mHandler.sendMessage(msg);
                        dataValid = true;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };
        receivePool.submit(runnable);
    }

}
